from fastapi import APIRouter, Depends, HTTPException, Response, Body
from sqlalchemy.orm import Session
from database import SessionLocal
from crud.user import create_user, get_user, get_all_users, update_user, delete_user, change_password
from schemas.user import UserCreate, UserResponse,TokenRefresh,ChangePasswordRequest
from utils.auth import create_access_token, create_refresh_token, ACCESS_TOKEN_EXPIRE_MINUTES, REFRESH_TOKEN_EXPIRE_MINUTES
from pydantic import BaseModel
from datetime import timedelta
import jwt
from jose import JWTError
from models.models import LearnUser
from utils.auth import SECRET_KEY, ALGORITHM, get_current_user
from utils.log_manager import app_logger

router = APIRouter(prefix="/users", tags=["Users"])

# 获取数据库连接
def get_db():

    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

class LoginRequest(BaseModel):
    email: str
    password: str

# 登录接口
@router.post("/login")
def login(request: LoginRequest, db: Session = Depends(get_db)):
    user = db.query(LearnUser).filter(LearnUser.email == request.email).first()
    if not user or not user.check_password(request.password):
        raise HTTPException(status_code=401, detail="邮箱或密码错误")

    access_token = create_access_token(data={"sub": str(user.id)}, expires_delta=timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES))
    refresh_token = create_refresh_token(data={"sub": str(user.id)}, expires_delta=timedelta(minutes=REFRESH_TOKEN_EXPIRE_MINUTES))
    return {"access_token": access_token, "refresh_token": refresh_token}

# 刷新 Token 接口
@router.post("/refresh")
def refresh_token(refresh_token: TokenRefresh = Body(...), db: Session = Depends(get_db)):
    try:
        payload = jwt.decode(refresh_token.refresh_token, SECRET_KEY, algorithms=[ALGORITHM])
        user_id: str = payload.get("sub")
        if not user_id:
            raise HTTPException(status_code=400, detail="无效的认证信息")
    except JWTError:
        raise HTTPException(status_code=400, detail="认证失败")
    except jwt.exceptions.DecodeError:
        raise HTTPException(status_code=400, detail="认证失败")
    except Exception as e:
        app_logger.error(f"Token 解析失败: {e}")
        raise HTTPException(status_code=400, detail="认证失败")


    user = db.query(LearnUser).filter(LearnUser.id == int(user_id)).first()
    if user is None:
        raise HTTPException(status_code=400, detail="用户不存在")

    new_access_token = create_access_token(data={"sub": str(user.id)})
    return {"access_token": new_access_token}

# 受保护的用户信息接口
@router.get("/me")
def get_user_info(user:LearnUser=Depends(get_current_user)):
    return user 


@router.post("/logout")
def logout(response: Response):
    response.delete_cookie(key="token")
    return {"message": "注销成功"}


@router.post("/change_password")
def change(request: ChangePasswordRequest, db: Session = Depends(get_db),user:LearnUser=Depends(get_current_user)):
    user = change_password(db, user.id, request.old_password, request.new_password)
    if user is None:
        raise HTTPException(status_code=400, detail="旧密码错误")
    return {"message": "密码修改成功"}


@router.post("/", response_model=UserResponse)
def add_user(user: UserCreate, db: Session = Depends(get_db)):
    db_user = create_user(db, user)
    if isinstance(db_user, ValueError):
        if db_user.args[0] == 1:
            raise HTTPException(status_code=400, detail="邮箱已存在")
        elif db_user.args[0] == 2:
            raise HTTPException(status_code=400, detail="用户名已存在")
    return db_user

@router.get("/{user_id}", response_model=UserResponse)
def read_user(user_id: int, db: Session = Depends(get_db)):
    user = get_user(db, user_id)
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    return user

@router.get("/", response_model=list[UserResponse])
def read_all_users(db: Session = Depends(get_db)):
    return get_all_users(db)

@router.put("/{user_id}", response_model=UserResponse)
def modify_user(user_id: int, username: str, email: str, db: Session = Depends(get_db)):
    updated_user = update_user(db, user_id, username, email)
    if not updated_user:
        raise HTTPException(status_code=404, detail="User not found")
    return updated_user

@router.delete("/{user_id}")
def remove_user(user_id: int, db: Session = Depends(get_db)):
    if delete_user(db, user_id):
        return {"message": "User deleted"}
    raise HTTPException(status_code=404, detail="User not found")
